#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include "serial.h"
#include "../include/logger.h"
#include "../include/shared_data.h"
#include "../include/json_par.h"
#include "../include/cJSON.h"
#include "../include/gpio.h"


#define GPIO_PORT 19
#define GPIO_SET 1
#define GPIO_RESET 0


pthread_mutex_t gpio_mutex = PTHREAD_MUTEX_INITIALIZER;



//初始化串口
int initialize_serial(const char *port_name, int baud_rate,int nBits, char nEvent, int nStop) {
    int serial_fd;
    serial_fd = open(port_name, O_RDWR | O_NOCTTY);
    if (serial_fd == -1) {
        writeLog(ERROR,__FILE__,__func__,"Failed to open serial port\n");
        //printf("Failed to open serial port\n");
        return -1;
    }

    set_serial_port_attributes(serial_fd,baud_rate,nBits,nEvent,nStop);

    return serial_fd;
}


// 从串口读取数据的函数
void *read_serial(void *arg) {
    int serial_fd = *((int *)arg);
    char buffer[1024];
    int cmd[1024];

    memset(buffer, 0, sizeof(buffer));
    
    while (1) {       
        int source,destination,type,client_socket;
		    //pthread_mutex_lock(&gpio_mutex);
	
		    // write_gpio_num(GPIO_PORT,GPIO_RESET);      
        while(read(serial_fd,buffer,1024) > 0){
            size_t cmd_len = strlen(buffer);
            for (int i = 0; i < cmd_len; i++) {
                cmd[i] = (int)buffer[i]; // 将字符转换为整数
            }
            
            // 使用互斥锁获取共享数据
            pthread_mutex_lock(&packet_mutex);
            client_socket = shared_packet.client_socket;
            source = shared_packet.source;
            destination = shared_packet.destination;
            type = shared_packet.type;
            pthread_mutex_unlock(&packet_mutex);

            char *jsonStr = createAndPackageJsonData(destination,source,type,cmd,cmd_len);
            writeLog(INFO,__FILE__,__func__,"收到串口%d的数据%s\n",find_serial_port(serial_fd),jsonStr);
            send(client_socket, jsonStr, strlen(jsonStr), 0);
            
            memset(buffer, 0, sizeof(buffer));
            memset(cmd, 0, sizeof(cmd));
			
        }
		//pthread_mutex_unlock(&gpio_mutex);  
		
    }
}
int send_serial_data(int fd,const char *data, int data_length) {
    // 在发送数据之前获取互斥锁
    //pthread_mutex_lock(&gpio_mutex);
    // write_gpio_num(GPIO_PORT,GPIO_SET);
    //writeLog(INFO,__FILE__,__func__,"send data = %s\n",data);
    //writeLog(INFO,__FILE__,__func__,"length=%d\n",data_length);
	  int bytes_written = write(fd, data, data_length);
    //write_gpio_num(GPIO_PORT,GPIO_RESET);
    //printf("send success\n");
    ///writeLog(INFO,__FILE__,__func__,"send success\n");
    if (bytes_written == -1) {
        //perror("Failed to write to serial port");
        writeLog(ERROR,__FILE__,__func__,"Failed to write to serial port\n");
        return -1;
    } else {
      writeLog(INFO,__FILE__,__func__,"write %d byte\n",bytes_written);
    }
    // write_gpio_num(GPIO_PORT,GPIO_RESET);
    // 发送完数据后释放互斥锁
    //pthread_mutex_unlock(&gpio_mutex);
    //printf("Sent data to serial port: %s\n", data);

    return 0;
}


//根据描述符确定哪个串口
int find_serial_port(int fd) {
    if(fd == serial_fd[0]) {
        return 1;
    } else if(fd == serial_fd[1]) {
        return 0;
    } else {
        return 2;
    }
}

#if 0
int main() {
    // 初始化和配置串口
    int serial_fd[NUM_SERIAL_PORTS];
    serial_fd[0] = initialize_serial("/dev/ttyS2", 38400, 8, 'N', 1); 
    serial_fd[1] = initialize_serial("/dev/ttyS3", 38400, 8, 'N', 1);
    char *serial_out="AT+PAIRSTOP\r\n";

    if (serial_fd[0] == -1 && serial_fd[1] == -1) {
        printf("初始化串口错误\n");
        exit(EXIT_FAILURE);
    }

    // 创建用于串口读取的线程
    pthread_t serial_threads[NUM_SERIAL_PORTS];
    for (int i = 0; i < NUM_SERIAL_PORTS; i++) {
        if (pthread_create(&serial_threads[i], NULL, read_serial, (void *)&serial_fd[i]) != 0) {
            perror("创建串口线程错误");
            exit(EXIT_FAILURE);
        }
    }
    write(serial_fd[0], serial_out, strlen(serial_out));
    printf("send success\n");
        


    for (int i = 0; i < NUM_SERIAL_PORTS; i++) {
        pthread_join(serial_threads[i], NULL);
    }

    // 关闭串口（这部分在本示例中不会执行到）
    for (int i = 0; i < NUM_SERIAL_PORTS; i++) {
        close(serial_fd[i]);
    }

    return 0;
}


#endif


int set_serial_port_attributes(int fd,int baud_rate,int nBits, char nEvent, int nStop) {
    // 设置串口参数，包括波特率，数据位，校验位，停止位
    struct termios newtio;
    //清空结构体
    memset(&newtio, 0, sizeof(struct termios));
    newtio.c_cflag  |=  CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;//清空数据位
    //newtio.c_cflag &= ~CRTSCTS; //无硬件流控制
    switch( nBits )
    {
        case 7:
            newtio.c_cflag |= CS7;
            break;
        case 8:
            newtio.c_cflag |= CS8;
            break;
    }

    switch( nEvent )
    {
        case 'O':
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            newtio.c_iflag |= (INPCK | ISTRIP);
            break;
        case 'E': 
            newtio.c_iflag |= (INPCK | ISTRIP);
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            break;
        case 'N':  
            newtio.c_cflag &= ~PARENB;
            break;
    }

    switch( baud_rate )
    {
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case 38400:
            cfsetispeed(&newtio, B38400);
            cfsetospeed(&newtio, B38400);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;       
        case 460800:
            cfsetispeed(&newtio, B460800);
            cfsetospeed(&newtio, B460800);
            break;
        default:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
    }
    if( nStop == 1 )
        newtio.c_cflag &=  ~CSTOPB;
    else if ( nStop == 2 )
        newtio.c_cflag |=  CSTOPB;


    newtio.c_cc[VTIME]  = 0;
    newtio.c_cc[VMIN] = 0;
    /* 刷新输出队列,清除正接受的数据 */
    tcflush(fd,TCIFLUSH);
    /* 改变配置 */
    if((tcsetattr(fd,TCSANOW,&newtio))!=0){
        //perror("serial set error");
        writeLog(ERROR,__FILE__,__func__,"serial set error\n");
        return -1;
    }
		
    //printf("serial set success!\r\n");
    writeLog(INFO,__FILE__,__func__,"serial set success!\n");
    return 0;
}
